package com.xneure.database.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.springframework.jdbc.core.JdbcTemplate;
import com.xneure.database.annotation.DBField;
import com.xneure.database.metaobject.FieldMetaObject;
import com.xneure.database.sql.QueryMappingParser;
import com.xneure.database.sql.handler.SqlHandler;
import com.xneure.utils.ObjectUtil;
import com.xneure.utils.SpringUtil;
import net.sf.cglib.proxy.LazyLoader;
/**
 * 
 * @author admin
 *
 */
public class DBLazyLoader implements LazyLoader {
	private static ThreadLocal<JdbcTemplate> template = new ThreadLocal<JdbcTemplate>() {
		@Override
		protected JdbcTemplate initialValue() {
			return SpringUtil.getJdbcTemplate();
		}
	};
	private Object obj;
	private FieldMetaObject field;

	public DBLazyLoader(Object obj, FieldMetaObject field) {
		this.obj = obj;
		this.field = field;
	}

	@Override
	public Object loadObject() throws Exception {
		Object res = null;
		QueryMappingParser qmp = new QueryMappingParser();
		StringBuilder where = new StringBuilder();
		DBField annotation = field.getAnnotation();
		where.append(annotation.where());
		where.append(annotation.value());
		where.append(" = ");
		if (obj instanceof DataBaseTable) {
			Object _value = ((DataBaseTable) obj).source.get(annotation.relation().toLowerCase());
			if (null == _value) {
				ObjectUtil.modifyFieldValue(obj, field.getName(), res);
				return null;
			} else {
				where.append(SqlHandler.getValueConvert().sqlValue(_value));
			}
		} else {
			where.append(SqlHandler.getValueConvert().sqlValue(ObjectUtil.getFieldValue(obj, annotation.relation())));
		}
		Class<?> targetType = qmp.getTargetType(field.getField(), annotation);
		List<Map<String, Object>> queryList;
		if (annotation.sql().isEmpty()) {
			queryList = template.get().queryForList(qmp.qurey(ObjectUtil.newInstance(targetType), where.toString()));
		} else {
			queryList = template.get().queryForList(annotation.sql().concat(" WHERE ".concat(where.toString())));
		}
		if (ObjectUtil.isNull(queryList) == false) {
			if (List.class.isAssignableFrom(field.getType())) {
				if (null != queryList) {
					List<Object> resObject = new ArrayList<>(queryList.size());
					for (Map<String, Object> map : queryList) {
						resObject.add(qmp.toObject(targetType, map));
					}
					res = resObject;
				}
			} else {
				res = qmp.toObject(targetType, queryList.get(0));
			}
		}
		if (null == res) {
			res = new ArrayList<Object>();
		}
		ObjectUtil.modifyFieldValue(obj, field.getName(), res);
		return res;
	}
}
